home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / TPL60N14.ARJ / DHRYSTON.PAS < prev    next >
Pascal/Delphi Source File  |  1992-03-28  |  31KB  |  843 lines

  1. {$A+,B-,D+,E+,F-,G-,I-,L+,N-,O-,R-,S-,V-,X-}
  2. {$M 16384,0,655360}
  3. (*
  4.  ****************************************************************************
  5.  *
  6.  *                   "DHRYSTONE" Benchmark Program
  7.  *                   -----------------------------
  8.  *
  9.  *  Version:    Pascal, Version 2.1
  10.  *
  11.  *  File:       dhry.p
  12.  *
  13.  *  Date:       May 25, 1988
  14.  *
  15.  *  Author:     Reinhold P. Weicker
  16.  *                      Siemens AG, E STE 35
  17.  *                      Postfach 3220
  18.  *                      8520 Erlangen
  19.  *                      Germany (West)
  20.  *                              Phone:  [xxx-49]-9131-7-20330
  21.  *                                      (8-17 Central European Time)
  22.  *                              Usenet: ..!mcvax!unido!estevax!weicker
  23.  *
  24.  *              Original Version (in Ada) published in
  25.  *              "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
  26.  *              pp. 1013 - 1030, together with the statistics
  27.  *              on which the distribution of statements etc. is based,
  28.  *
  29.  *              This version uses calls to the Pascal runtime library of the
  30.  *              Berkeley UNIX system (4.3 bsd) for time measurement.
  31.  *              For measurements on other systems, these calls need to be
  32.  *              modified.
  33.  *
  34.  *  Collection of Results:
  35.  *              Reinhold Weicker (address see above) and
  36.  *
  37.  *              Rick Richardson
  38.  *              PC Research. Inc.
  39.  *              94 Apple Orchard Drive
  40.  *              Tinton Falls, NJ 07724
  41.  *                      Phone:  (201) 834-1378 (9-17 EST)
  42.  *                      Usenet: ...!seismo!uunet!pcrat!rick
  43.  *
  44.  *      Please send results to Rick Richardson and/or Reinhold Weicker.
  45.  *      Complete information should be given on hardware and software used.
  46.  *      Hardware information includes: Machine type, CPU, type and size
  47.  *      of caches; for microprocessors: clock frequency, memory speed
  48.  *      (number of wait states).
  49.  *      Software information includes: Compiler (and runtime library)
  50.  *      manufacturer and version, compilation switches, OS version.
  51.  *      The Operating System version may give an indication about the
  52.  *      compiler; Dhrystone itself performs no OS calls in the measurement loop.
  53.  *
  54.  *      The complete output generated by the program should be mailed
  55.  *      such that at least some checks for correctness can be made.
  56.  *
  57.  ****************************************************************************
  58.  *
  59.  *  History:    This version Pascal/2.1 has been made for two reasons:
  60.  *
  61.  *              1) There is a need for a common Pascal version of
  62.  *              Dhrystone. Although translation from the published (Ada)
  63.  *              version to Pascal is straightforward in most aspects,
  64.  *              there are cases where it may not be obvious to everyone.
  65.  *              There should be, as far as possible, only one Pascal version
  66.  *              of Dhrystone such that results can be compared without
  67.  *              restrictions. Also, a Pascal version of Dhrystone has not yet
  68.  *              found a network distribution comparable to the C version
  69.  *              (version 1.1) distributed by Rick Richardson.
  70.  *
  71.  *              2) As far as it is possible without changes to the Dhrystone
  72.  *              statistics, optimizing compilers should be prevented from
  73.  *              removing significant statements.
  74.  *
  75.  *              This Pascal version 2.1 has been made consistent with the
  76.  *              C version 2.1; therefore the acknowledgments for the C version
  77.  *              are due for the Pascal version as well: I thank
  78.  *              Rick Richardson (Tinton Falls, NJ), Chaim Benedelac (Nat.
  79.  *              Semi.), David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
  80.  *              Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
  81.  *              for their help with comments on earlier versions of the
  82.  *              benchmark.
  83.  *
  84.  *  Changes:    In the initialization part, this version differs
  85.  *              from the Pascal version previously distributed by Reinhold
  86.  *              Weicker, the number of runs through Dhrystone is obtained
  87.  *              interactively from the terminal. Output of the result
  88.  *              has been changed to conform to the C version (2.1).
  89.  *              The changes in the initialization part and in the printing
  90.  *              of the result have no impact on performance measurement
  91.  *              since they are outside the measaurement loop.
  92.  *
  93.  *              Inside the measurement loop, this version follows the
  94.  *              version previously distributed by Reinhold Weicker.
  95.  *              As a correction to the published version, a statement
  96.  *              initializing Array2Glob [8,7] (outside the measurement
  97.  *              loop) has been added. Otherwise, this array element would
  98.  *              have an undefined value.
  99.  *
  100.  *              At several places in the benchmark, code has been added,
  101.  *              but within the measurement loop only in branches that
  102.  *              are not executed. The intention is that optimizing compilers
  103.  *              should be prevented from moving code out of the measurement
  104.  *              loop, or from removing code altogether. Since the statements
  105.  *              that are executed within the measurement loop have NOT been
  106.  *              changed, all numbers defining the "Dhrystone distribution"
  107.  *              (distribution of statements, operand types and locality)
  108.  *              still hold. Except for sophisticated optimizing compilers,
  109.  *              execution times for this version should be the same as
  110.  *              for previous versions.
  111.  *
  112.  *              Since it has proven difficult to subtract the time for the
  113.  *              measurement loop overhead in a correct way, the loop check
  114.  *              has been made a part of the benchmark. This does have
  115.  *              an impact - though a very minor one - on the distribution
  116.  *              statistics which have been updated for this version.
  117.  *
  118.  *              All changes within the measurement loop are described
  119.  *              and discussed in the companion paper "Rationale for
  120.  *              Dhrystone version 2".
  121.  *
  122.  *              Because of the self-imposed limitation that the order and
  123.  *              distribution of the executed statements should not be
  124.  *              changed, there are still cases where optimizing compilers
  125.  *              may not generate code for some statements. To a certain
  126.  *              degree, this is unavoidable for small synthetic benchmarks.
  127.  *              Users of the benchmark are advised to check code listings
  128.  *              whether code is generated for all statements of Dhrystone.
  129.  *
  130.  *              Version 2.1 is identical to version 2.0 distributed via
  131.  *              the UNIX network Usenet in March 1988 except that it corrects
  132.  *              some minor deficiencies that were found by users of version 2.0.
  133.  *              The only change within the measurement loop is that a
  134.  *              non-executed "else" part was added to the "if" statement in
  135.  *              Func3, and a non-executed "else" part removed from Proc3.
  136.  *
  137.  ***************************************************************************
  138.  *
  139.  *  Compilation model and measurement (IMPORTANT):
  140.  *
  141.  *  This program contains the Dhrystone program, including measurement setup,
  142.  *  in one file. The original (Ada) program contained three packages,
  143.  *  - a package with global type definitions,
  144.  *  - Pack_1, containing the main program (Proc_0 in Ada) and procedures
  145.  *            Proc_1, ... , Proc_5,
  146.  *  - Pack_2, containing Proc_6, ... , Proc_8, Func_1, ..., Func_3.
  147.  *  Since ISO/ANSI Standard Pascal provides no means to express separate
  148.  *  compilation (although many Pascal implementations provide such a feature),
  149.  *  it is not possible to formulate a portable Pascal version with the program
  150.  *  in several modules, corresponding more closely to the Ada and C versions.
  151.  *  Therefore, no attempt has been made to construct a Pascal version with
  152.  *  the program consisting of several modules.
  153.  *
  154.  *  This difference may impact execution time because the compiler can
  155.  *  perform more data flow analysis for a single-module program;
  156.  *  sophisticated compilers may be able to suppress code generation for
  157.  *  some parts of the program.
  158.  *  Users should check machine code listings generated by the compiler
  159.  *  to ensure that code is generated for all parts of the program.
  160.  *
  161.  *  The following "ground rules" apply for measurements:
  162.  *  - No procedure merging
  163.  *  - Otherwise, compiler optimizations are allowed but should be indicated
  164.  *  See the companion paper "Rationale for Dhrystone Version 2" for a more
  165.  *  detailed discussion of these ground rules.
  166.  *
  167.  *  For 16-Bit processors (e.g. 80x86), times for all compilation models
  168.  *  ("small", "medium", "large") should be given if possible, together
  169.  *  with a definition of these models for the compiler system used.
  170.  *
  171.  **************************************************************************
  172.  *
  173.  *  Dhrystone (Pascal version) statistics:
  174.  *
  175.  *  [Comment from the first distribution by Reinhold Weicker,
  176.  *   the distribution statistics have been updated for Version 2.1.
  177.  *   Note that because of language differences, the numbers are different
  178.  *   from the Ada version. The main difference is that the variables that
  179.  *   are local variables of "Proc_0" (Ada) or "main" (C) are global
  180.  *   variables in the Pascal version.]
  181.  *
  182.  *  The following program contains statements of a high level programming
  183.  *  language (here: Pascal) in a distribution considered representative:
  184.  *
  185.  *    assignments                  58
  186.  *    control statements           28
  187.  *    procedure, function calls    15
  188.  *
  189.  *  100 statements are dynamically executed. The program is balanced with
  190.  *  respect to the three aspects:
  191.  *
  192.  *    - statement type
  193.  *    - operand type (for simple data types)
  194.  *    - operand access
  195.  *         operand global, local, parameter, or constant.
  196.  *           There is no static nesting of blocks or procedures,
  197.  *           therefore all variables are either global or local.
  198.  *
  199.  *  The combination of these three aspects is balanced only approximately.
  200.  *
  201.  *  1. Statement Type:
  202.  *  -----------------             number
  203.  *
  204.  *     V1 := V2                   15
  205.  *     V := Constant              12
  206.  *       (incl. V1 := F(..)
  207.  *     Assignment,                 7
  208.  *       with array element
  209.  *     Assignment,                 6
  210.  *       with record component
  211.  *                                --
  212.  *                                40       40
  213.  *
  214.  *     X := Y +|-|and|or Z         5
  215.  *     X := Y +|-|"=" Constant     6
  216.  *     X := X +|- 1                3
  217.  *     X := Y *|/ Z                2
  218.  *     X := Expression,            1
  219.  *          two operators
  220.  *     X := Expression,            1
  221.  *          three operators
  222.  *                                --
  223.  *                                18       18
  224.  *
  225.  *     if .... then ....          14
  226.  *       with "else"      7
  227.  *       without "else"   7
  228.  *           executed        3
  229.  *           not executed    4
  230.  *     for I in 1..N do ...        7  |  counted every time
  231.  *     while ... do ...            4  |  the loop condition
  232.  *     repeat ... until            1  |  is evaluated
  233.  *     case ... end                1
  234.  *     with                        1
  235.  *                                --
  236.  *                                28       28
  237.  *
  238.  *     P (...)  procedure call    10
  239.  *     X := F (...)
  240.  *             function  call      5
  241.  *                                --
  242.  *                                15       15
  243.  *                                        ---
  244.  *                                        101
  245.  *
  246.  *    22 of the 58 assignments have a variable of a constrained
  247.  *    (sub-)type as their destination. In general, discriminant checks
  248.  *    will be necessary in these cases; however, the compiler may
  249.  *    optimize out some of these checks.
  250.  *
  251.  *    The average number of parameters in procedure or function calls
  252.  *    is 1.80 (not counting the function values as implicit parameters).
  253.  *
  254.  *
  255.  *  2. Operators
  256.  *  ------------
  257.  *                          number    approximate
  258.  *                                    percentage
  259.  *
  260.  *    Arithmetic             27          52.9
  261.  *
  262.  *       +                     16          31.4
  263.  *       -                      7          13.7
  264.  *       *                      3           5.9
  265.  *       div                    1           2.0
  266.  *
  267.  *    Comparison             20           39.2
  268.  *
  269.  *       =                      9           17.6
  270.  *       <>                     4            7.8
  271.  *       >                      1            2.0
  272.  *       <                      3            5.9
  273.  *       >=                     1            2.0
  274.  *       <=                     2            3.9
  275.  *
  276.  *    Logic                   4            7.8
  277.  *
  278.  *       AND                    1            2.0
  279.  *       OR                     1            2.0
  280.  *       NOT                    2            3.9
  281.  *
  282.  *                           --          -----
  283.  *                           51           99.9
  284.  *
  285.  *
  286.  *  3. Operand Type (counted once per operand reference):
  287.  *  ---------------
  288.  *                          number    approximate
  289.  *                                    percentage
  290.  *
  291.  *     Integer               135        54.7 %
  292.  *     Character              47        19.0 %
  293.  *     Enumeration            31        12.6 %
  294.  *     Boolean                13         5.3 %
  295.  *     Pointer                11         4.5 %
  296.  *     String30                6         2.4 %
  297.  *     Array                   2         0.8 %
  298.  *     Record                  2         0.8 %
  299.  *                           ---       -------
  300.  *                           247        100.1 %
  301.  *
  302.  *  When there is an access path leading to the final operand (e.g. a record
  303.  *  component), only the final data type on the access path is counted.
  304.  *
  305.  *  There are 16 accesses to components of a record, 9 of them go to
  306.  *  a component in a variant part. For some of these accesses, the
  307.  *  compiler may suppress generation of code checking the tag field
  308.  *  during optimization.
  309.  *
  310.  *
  311.  *  3. Operand Locality:
  312.  *  -------------------
  313.  *
  314.  *     local variable               84        34.0 %
  315.  *     global variable              58        23.5 %
  316.  *     parameter                    45        18.2 %
  317.  *        value                        23         9.3 %
  318.  *        reference                    22         8.9 %
  319.  *     function result               5         2.0 %
  320.  *     constant                     55        22.3 %
  321.  *                                 ---       -------
  322.  *                                 247       100.0 %
  323.  *
  324.  *
  325.  *  The program does not compute anything meaningful, but it is syntactically
  326.  *  and semantically correct. All variables have a value assigned to them
  327.  *  before they are used as a source operand.
  328.  *
  329.  *  There may be cases where a highly optimizing compiler may recognize
  330.  *  unnecessary statements and may not generate code for them.
  331.  *
  332.  *  There has been no explicit effort to account for the effects of a
  333.  *  cache, or to balance the use of long or short displacements for code or
  334.  *  data.
  335.  *
  336.  ****************************************************************************
  337.  *)
  338.  
  339. program Dhrystone (input, output);
  340. (***************)
  341. uses time;
  342. const (* for measurement *)
  343.  
  344.   MicrosecondsPerClock  = 1000;
  345.   ClocksPerSecond       = 1000;
  346.         (* In Berkeley UNIX Pascal, the function "clock"        *)
  347.         (* returns milliseconds                                 *)
  348.   TooSmallTime          = 2000;
  349.         (* Measurements should last at least 2 seconds          *)
  350.  
  351. type
  352.  
  353.   (* Global type definitions *)
  354.  
  355.   Enumeration           = (Ident1, Ident2, Ident3, Ident4, Ident5);
  356.  
  357.   OneToThirty           = 1..30;
  358.   OneToFifty            = 1..50;
  359.   CapitalLetter         = 'A'..'Z';
  360.  
  361.   String30              = packed array [OneToThirty] of char;
  362.  
  363.  
  364.   Array1DimInteger      = array [OneToFifty] of integer;
  365.   Array2DimInteger      = array [OneToFifty, OneToFifty] of integer;
  366.  
  367.   RecordPointer         = ^RecordType;
  368.  
  369.   RecordType            =
  370.       record
  371.         PointerComp:   RecordPointer;
  372.         case Discr:    Enumeration of
  373.           Ident1:         (* only this variant is used,           *)
  374.                           (* but in some cases discriminant       *)
  375.                           (* checks are necessary                 *)
  376.             (EnumComp:      Enumeration;
  377.              IntComp:       OneToFifty;
  378.              StringComp:    String30);
  379.           Ident2:
  380.             (Enum2Comp:    Enumeration;
  381.              String2Comp:  String30);
  382.           Ident3, Ident4, Ident5:
  383.             (Char1Comp,
  384.              Char2Comp:    char);
  385.       end; (* record *)
  386.  
  387. var
  388.  
  389.   (* Ada version: Variables local in Proc_0 *)
  390.  
  391.   Int1Glob,
  392.   Int2Glob,
  393.   Int3Glob:       OneToFifty;
  394.   CharIndex:      char;
  395.   EnumGlob:       Enumeration;
  396.   String1Glob,
  397.   String2Glob:    String30;
  398.  
  399.   (* Ada version: Variables global in Pack_1 *)
  400.  
  401.   PointerGlob,
  402.   NextPointerGlob: RecordPointer;
  403.   IntGlob:         integer;
  404.  
  405.   BoolGlob:        boolean;
  406.   Char1Glob,
  407.   Char2Glob:       char;
  408.   Array1Glob:      Array1DimInteger;
  409.   Array2Glob:      Array2DimInteger;
  410.  
  411.   (* Variables for measurement *)
  412.  
  413.   RunIndex,
  414.   NumberOfRuns:         integer;
  415.   BeginClock,
  416.   EndClock,
  417.   SumClocks:            longint;
  418.   Microseconds,
  419.   DhrystonesPerSecond:  real;
  420.   I:                    integer;
  421.  
  422.   (* end of variables for measurement *)
  423.  
  424. procedure Proc1 (    PointerParVal: RecordPointer);     forward;
  425.  
  426. procedure Proc2 (var IntParRef:     OneToFifty);        forward;
  427.  
  428. procedure Proc3 (var PointerParRef: RecordPointer);     forward;
  429.  
  430. procedure Proc4;                                        forward;
  431.   (* without parameters *)
  432.  
  433. procedure Proc5;                                        forward;
  434.   (* without parameters *)
  435.  
  436. procedure Proc6 (    EnumParVal:    Enumeration;
  437.                  var EnumParRef:    Enumeration);       forward;
  438.  
  439. procedure Proc7 (    Int1ParVal,
  440.                      Int2ParVal:    OneToFifty;
  441.                  var IntParRef:     OneToFifty);        forward;
  442.  
  443. procedure Proc8 (var Array1ParRef:  Array1DimInteger;
  444.                  var Array2ParRef:  Array2DimInteger;
  445.                      Int1ParVal,
  446.                      Int2ParVal:    integer);            forward;
  447.  
  448. function Func1  (    Char1ParVal,
  449.                      Char2ParVal:   CapitalLetter):
  450.                                             Enumeration; forward;
  451.  
  452. function Func2  (var String1ParRef,
  453.                      String2ParRef: String30):
  454.                                             boolean;      forward;
  455.  
  456. function Func3  (    EnumParVal:    Enumeration):
  457.                                             boolean;      forward;
  458.  
  459.  
  460. procedure Proc1; (* (PointerParVal: RecordPointer) *)
  461.     (* executed once *)
  462. begin
  463.   with PointerParVal^.PointerComp^ (* = PointerGlobNext *) do
  464.   begin
  465.     PointerParVal^.PointerComp^ := PointerGlob^;
  466.     PointerParVal^.IntComp := 5;
  467.     IntComp := PointerParVal^.IntComp;
  468.     PointerComp := PointerParVal^.PointerComp;
  469.     Proc3 (PointerComp);
  470.       (* PointerParVal^.PointerComp^.PointerComp = PointerGlob^.PointerComp *)
  471.     if Discr = Ident1
  472.     then (* executed *)
  473.     begin
  474.       IntComp := 6;
  475.       Proc6 (PointerParVal^.EnumComp, EnumComp);
  476.       PointerComp := PointerGlob^.PointerComp;
  477.       Proc7 (IntComp, 10, IntComp);
  478.     end (* then *)
  479.     else (* not executed *)
  480.       PointerParVal^ := PointerParVal^.PointerComp^;
  481.   end; (* with *)
  482. end; (* Proc1 *)
  483.  
  484.  
  485. procedure Proc2; (* (var IntParRef: OneToFifty) *)
  486.     (* executed once *)
  487.     (* InParRef = 3, becomes 7 *)
  488. var
  489.   IntLoc:  OneToFifty;
  490.   EnumLoc: Enumeration;
  491. begin
  492.   IntLoc := IntParRef + 10;
  493.   repeat (* executed once *)
  494.     if Char1Glob = 'A'
  495.     then (* executed *)
  496.     begin
  497.       IntLoc := IntLoc - 1;
  498.       IntParRef := IntLoc - IntGlob;
  499.       EnumLoc := Ident1;
  500.     end (* if *)
  501.   until EnumLoc = Ident1; (* true *)
  502. end; (* Proc2 *)
  503.  
  504.  
  505. procedure Proc3; (* (var PointerParRef: RecordPointer) *)
  506.     (* executed once *)
  507.     (* PointerParRef becomes PointerGlob *)
  508. begin
  509.   if PointerGlob <> nil
  510.   then (* executed *)
  511.     PointerParRef := PointerGlob^.PointerComp;
  512.   Proc7 (10, IntGlob, PointerGlob^.IntComp);
  513. end; (* Proc3 *)
  514.  
  515.  
  516. procedure Proc4; (* without parameters *)
  517.     (* executed once *)
  518. var
  519.   BoolLoc: boolean;
  520. begin
  521.   BoolLoc := Char1Glob = 'A';
  522.   BoolGlob := BoolLoc or BoolGlob;
  523.   Char2Glob := 'B';
  524. end; (* Proc4 *)
  525.  
  526.  
  527. procedure Proc5; (* without parameters *)
  528.     (* executed once *)
  529. begin
  530.   Char1Glob := 'A';
  531.   BoolGlob := false;
  532. end; (* Proc5 *)
  533.  
  534.  
  535. procedure Proc6; (* (    EnumParVal:     Enumeration;
  536.                      var EnumParRef:     Enumeration) *)
  537.     (* executed once *)
  538.     (* EnumParVal = Ident3, EnumParRef becomes Ident2 *)
  539. begin
  540.   EnumParRef := EnumParVal;
  541.   if not Func3 (EnumParVal)
  542.   then (* not executed *)
  543.     EnumParRef := Ident4;
  544.   case EnumParVal of
  545.     Ident1: EnumParRef := Ident1;
  546.     Ident2: if IntGlob > 100
  547.               then EnumParRef := Ident1
  548.               else EnumParRef := Ident4;
  549.     Ident3: EnumParRef := Ident2;    (* executed *)
  550.     Ident4: ;
  551.     Ident5: EnumParRef := Ident3;
  552.   end; (* case *)
  553. end; (* Proc6 *)
  554.  
  555.  
  556. procedure Proc7; (* (    Int1ParVal,
  557.                          Int2ParVal:    OneToFifty;
  558.                      var IntParRef:     OneToFifty) *)
  559.     (* executed three times                               *)
  560.     (* first call:      Int1ParVal = 2, Int2ParVal = 3,   *)
  561.     (*                  IntParRef becomes 7               *)
  562.     (* second call:     Int1ParVal = 10, Int2ParVal = 5,  *)
  563.     (*                  IntParRef becomes 17              *)
  564.     (* third call:      Int1ParVal = 6, Int2ParVal = 10,  *)
  565.     (*                  IntParRef becomes 18              *)
  566. var
  567.   IntLoc: OneToFifty;
  568. begin
  569.   IntLoc := Int1ParVal + 2;
  570.   IntParRef := Int2ParVal + IntLoc;
  571. end; (* Proc7 *)
  572.  
  573.  
  574. procedure Proc8; (* (var Array1ParRef: Array1DimInteger;
  575.                      var Array2ParRef: Array2DimInteger;
  576.                          Int1ParVal,
  577.                          Int2ParVal:    integer)          *)
  578.     (* executed once  *)
  579.     (* Int1ParVal = 3 *)
  580.     (* Int2ParVal = 7 *)
  581. var
  582.   IntIndex,
  583.   IntLoc:   OneToFifty;
  584. begin
  585.   IntLoc := Int1ParVal + 5;
  586.   Array1ParRef [IntLoc] := Int2ParVal;
  587.   Array1ParRef [IntLoc+1] := Array1ParRef [IntLoc];
  588.   Array1ParRef [IntLoc+30] := IntLoc;
  589.   for IntIndex := IntLoc to IntLoc+1 do
  590.     Array2ParRef [IntLoc, IntIndex] := IntLoc;
  591.   Array2ParRef [IntLoc, IntLoc-1] := Array2ParRef [IntLoc, IntLoc-1] + 1;
  592.   Array2ParRef [IntLoc+20, IntLoc] := Array1ParRef [IntLoc];
  593.   IntGlob := 5;
  594. end; (* Proc8 *)
  595.  
  596.  
  597. function Func1; (* (Char1ParVal,
  598.                     Char2ParVal: CapitalLetter): Enumeration *)
  599.     (* executed three times, returns always Ident1              *)
  600.     (* first call:      Char1ParVal = 'H', Char2ParVal = 'R'    *)
  601.     (* second call:     Char1ParVal = 'A', Char2ParVal = 'C'    *)
  602.     (* third call:      Char1ParVal = 'B', Char2ParVal = 'C'    *)
  603. var
  604.   Char1Loc, Char2Loc: CapitalLetter;
  605. begin
  606.   Char1Loc := Char1ParVal;
  607.   Char2Loc := Char1Loc;
  608.   if Char2Loc <> Char2ParVal
  609.   then  (* executed *)
  610.     Func1 := Ident1
  611.   else  (* not executed *)
  612.   begin
  613.     Char1Glob := Char1Loc;
  614.     Func1 := Ident2;
  615.   end;
  616. end; (* Func1 *)
  617.  
  618.  
  619. function Func2; (* (var String1ParRef,
  620.                         String2ParRef: String30): boolean *)
  621.     (* executed once, returns false              *)
  622.     (* String1ParRef = 'DHRYSTONE PROGRAM, 1''ST STRING' *)
  623.     (* String2ParRef = 'DHRYSTONE PROGRAM, 2''ND STRING' *)
  624. var
  625.   IntLoc:  OneToThirty;
  626.   CharLoc: CapitalLetter;
  627. begin
  628.   IntLoc := 2;
  629.   while IntLoc <= 2 do (* loop body executed once *)
  630.     if Func1 (String1ParRef[IntLoc],
  631.               String2ParRef[IntLoc+1]) = Ident1
  632.     then (* executed *)
  633.     begin
  634.       CharLoc := 'A';
  635.       IntLoc := IntLoc + 1;
  636.     end; (* if, while *)
  637.   if (CharLoc >= 'W') and (CharLoc < 'Z')
  638.   then (* not executed *)
  639.     IntLoc := 7;
  640.   if CharLoc = 'R'
  641.   then (* not executed *)
  642.     Func2 := true
  643.   else (* executed *)
  644.   begin
  645.     if String1ParRef > String2ParRef
  646.     then (* not executed *)
  647.     begin
  648.       IntLoc := IntLoc + 7;
  649.       IntGlob := IntLoc;
  650.       Func2 := true
  651.     end
  652.     else (* executed *)
  653.       Func2 := false;
  654.   end; (* if CharLoc *)
  655. end; (* Func2 *)
  656.  
  657.  
  658. function Func3; (* (EnumParVal: Enumeration): boolean *)
  659.     (* executed once, returns true      *)
  660.     (* EnumParVal = Ident3              *)
  661. var
  662.   EnumLoc:  Enumeration;
  663. begin
  664.   EnumLoc := EnumParVal;
  665.   if EnumLoc = Ident3
  666.   then (* executed *)
  667.     Func3 := true
  668.   else (* not executed *)
  669.     Func3 := false;
  670. end; (* Func3 *)
  671.  
  672.  
  673. begin (* main program, corresponds to procedures        *)
  674.       (* Main and Proc_0 in the Ada version             *)
  675.  
  676.   (* Initializations *)
  677.  
  678.   new (NextPointerGlob);
  679.  
  680.   new (PointerGlob);
  681.  
  682.   PointerGlob^.PointerComp := NextPointerGlob;
  683.   PointerGlob^.Discr       := Ident1;
  684.   PointerGlob^.EnumComp    := Ident3;
  685.   PointerGlob^.IntComp     := 40;
  686.   PointerGlob^.StringComp  := 'DHRYSTONE PROGRAM, SOME STRING';
  687.  
  688.   String1Glob := 'DHRYSTONE PROGRAM, 1''ST STRING';
  689.  
  690.   Array2Glob [8,7] := 10;
  691.  
  692.   writeln;
  693.   writeln ('Dhrystone Benchmark, Version 2.1 (Language: Pascal)');
  694.   writeln;
  695.   write   ('Please give the number of runs through the benchmark: ');
  696.   readln (NumberOfRuns);
  697.   writeln;
  698.   writeln ('Execution starts, ', NumberOfRuns : 7, ' runs through Dhrystone');
  699.  
  700.   BeginClock := Clock;
  701.  
  702.   (***************)
  703.   (* Start timer *)
  704.   (***************)
  705.  
  706.   for RunIndex := 1 to NumberOfRuns do
  707.   begin
  708.  
  709.     Proc5;
  710.     Proc4;
  711.       (* Char1Glob = 'A', Char2Glob = 'B', BoolGlob = false *)
  712.     Int1Glob := 2;
  713.     Int2Glob := 3;
  714.     String2Glob := 'DHRYSTONE PROGRAM, 2''ND STRING';
  715.     EnumGlob := Ident2;
  716.     BoolGlob := not Func2 (String1Glob, String2Glob);
  717.       (* BoolGlob = true *)
  718.     while Int1Glob < Int2Glob do  (* loop body executed once *)
  719.     begin
  720.       Int3Glob := 5 * Int1Glob - Int2Glob;
  721.         (* Int3Glob = 7 *)
  722.       Proc7 (Int1Glob, Int2Glob, Int3Glob);
  723.         (* Int3Glob = 7 *)
  724.       Int1Glob := Int1Glob + 1;
  725.     end; (* while *)
  726.       (* Int1Glob = 3 *)
  727.     Proc8 (Array1Glob, Array2Glob, Int1Glob, Int3Glob);
  728.       (* IntGlob = 5 *)
  729.     Proc1 (PointerGlob);
  730.     for CharIndex := 'A' to Char2Glob do   (* loop body executed twice *)
  731.       if EnumGlob = Func1 (CharIndex, 'C')
  732.         then (* not executed *)
  733.         begin
  734.           Proc6 (Ident1, EnumGlob);
  735.           String2Glob := 'DHRYSTONE PROGRAM, 3''RD STRING';
  736.           Int2Glob := RunIndex;
  737.           IntGlob := RunIndex;
  738.         end;
  739.     (* Int1Glob = 3, Int2Glob = 3, Int3Glob = 7 *)
  740.     Int2Glob := Int2Glob * Int1Glob;
  741.     Int1Glob := Int2Glob div Int3Glob;
  742.     Int2Glob := 7 * (Int2Glob - Int3Glob) - Int1Glob;
  743.       (* Int1Glob = 1, Int2Glob = 13, Int3Glob = 7 *)
  744.     Proc2 (Int1Glob);
  745.       (* Int1Glob = 5 *)
  746.  
  747.   end; (* for RunIndex *)
  748.  
  749.   EndClock := Clock;
  750.  
  751.   (**************)
  752.   (* Stop timer *)
  753.   (**************)
  754.  
  755.   writeln ('Execution ends');
  756.   writeln;
  757.   writeln ('Final values of the variables used in the benchmark:');
  758.   writeln;
  759.  
  760.   writeln ('IntGlob:                      ', IntGlob : 5);
  761.   writeln ('        should be:                5');
  762.   write ('BoolGlob:                      ');
  763.   if BoolGlob = true
  764.   then
  765.     writeln ('TRUE')
  766.   else
  767.     writeln ('FALSE');
  768.   writeln ('        should be:             TRUE');
  769.   writeln ('Char1Glob:                        ', Char1Glob);
  770.   writeln ('        should be:                A');
  771.   writeln ('Char2Glob:                        ', Char2Glob);
  772.   writeln ('        should be:                B');
  773.   writeln ('Array1Glob [8]:               ', Array1Glob [8] : 5);
  774.   writeln ('        should be:                7');
  775.   writeln ('Array2Glob [8,7]:             ', Array2Glob [8,7] : 5);
  776.   writeln ('        should be:                NumberOfRuns + 10');
  777.   writeln ('PointerGlob^.Discr:           ', ord (PointerGlob^.Discr) : 5);
  778.   writeln ('        should be:                0');
  779.   writeln ('PointerGlob^.EnumComp:        ', ord (PointerGlob^.EnumComp) : 5);
  780.   writeln ('        should be:                2');
  781.   writeln ('PointerGlob^.IntComp  :       ', PointerGlob^.IntComp : 5);
  782.   writeln ('        should be:               17');
  783.   write   ('PointerGlob^.StringComp:     ');
  784.   for I := 1 to 30 do
  785.     write (PointerGlob^.StringComp [I]);
  786.   writeln;
  787.   writeln ('        should be:           DHRYSTONE PROGRAM, SOME STRING');
  788.   writeln ('NextPointerGlob^.Discr:       ', ord (NextPointerGlob^.Discr) : 5);
  789.   writeln ('        should be:                0');
  790.   writeln ('NextPointerGlob^.EnumComp:    ',
  791.                     ord (NextPointerGlob^.EnumComp) : 5);
  792.   writeln ('        should be:                1');
  793.   writeln ('NextPointerGlob^.IntComp:     ', NextPointerGlob^.IntComp : 5);
  794.   writeln ('        should be:               18');
  795.   write   ('NextPointerGlob^.StringComp: ');
  796.   for I := 1 to 30 do
  797.     write (NextPointerGlob^.StringComp [I]);
  798.   writeln;
  799.   writeln ('        should be:           DHRYSTONE PROGRAM, SOME STRING');
  800.   writeln ('Int1Glob:                     ', Int1Glob : 5);
  801.   writeln ('        should be:                5');
  802.   writeln ('Int2Glob:                     ', Int2Glob : 5);
  803.   writeln ('        should be:               13');
  804.   writeln ('Int3Glob:                     ', Int3Glob : 5);
  805.   writeln ('        should be:                7');
  806.   writeln ('EnumGlob:                     ', ord (EnumGlob) : 5);
  807.   writeln ('        should be:                1');
  808.   write   ('String1Glob:                 ');
  809.   for I := 1 to 30 do
  810.     write (String1Glob [I]);
  811.   writeln;
  812.   writeln ('        should be:           DHRYSTONE PROGRAM, 1''ST STRING');
  813.   write   ('String2Glob:                 ');
  814.   for I := 1 to 30 do
  815.     write (String2Glob [I]);
  816.   writeln;
  817.   writeln ('        should be:           DHRYSTONE PROGRAM, 2''ND STRING');
  818.   writeln;
  819.   writeln;
  820.  
  821.   SumClocks := EndClock - BeginClock;
  822.  
  823.   if SumClocks < TooSmallTime
  824.     then
  825.     begin
  826.       writeln ('Measured time too small to obtain meaningful results');
  827.       writeln ('Please increase number of runs');
  828.       writeln;
  829.     end
  830.     else
  831.     begin
  832.       Microseconds := SumClocks * (MicrosecondsPerClock / NumberOfRuns);
  833.                                 (* Brackets to prevent integer overflow *)
  834.       DhrystonesPerSecond := NumberOfRuns * (ClocksPerSecond / SumClocks);
  835.       write ('Microseconds for one run through Dhrystone: ');
  836.       writeln (Microseconds : 8 : 1);
  837.       write ('Dhrystones per Second:                      ');
  838.       writeln (DhrystonesPerSecond : 8 : 1);
  839.       writeln;
  840.     end;
  841.  
  842. end.
  843.